/**
 * 
 */
package io.potato.core;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 提供最基础的增删改查功能
 * @author timl
 *
 */
public abstract class CrudService<T extends BaseEntity, PK> extends BaseService {
	
	/**
	 * 返回数据库操作对象
	 * @return JpaRepository object
	 */
	protected abstract JpaRepository<T, PK> getRepository();
	
	/**
	 * 根据ID查询
	 * @param id  唯一ID
	 * @return  Optional T
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public Optional<T> findById(PK id) {
		return this.getRepository().findById(id);
	}
	
	/**
	 *      根据ID查询, 记录不存在 返回null
	 * @param id  要查询的id
	 * @return
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public T getOne(PK id) {
		try {
			return this.getRepository().getOne(id);
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	/**
	 * 返回指定ID是否存在
	 * @param id  id
	 * @return  true 如果id存在 否则false
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public boolean existsById(PK id) {
		return getRepository().existsById(id);
	}
	
	/**
	 * 保存到数据库
	 * @param entity  要保存的实体类
	 * @return  保存后的实体类， id会有值
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public T save(T entity) {
		return this.getRepository().save(entity);
	}
	
	/**
	 * 保存列表到数据库
	 * @param list  实体列表
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public List<T> saveAll(Iterable<T> list) {
		return this.getRepository().saveAll(list);
	}
	
	/**
	 * 根据主键删除记录
	 * @param id  唯一ID
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void deleteById(PK id) {
		this.getRepository().deleteById(id);
	}
	
	/**
	 * 根据主键批量删除记录
	 * 
	 * param ids 主键集
	 */
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRED)
	public void deleteBatch(PK[] ids){
		for(PK id : ids){
			deleteById(id);
		}
	}
	
	/**
	 * 查询所有记录
	 * @return  所有记录
	 */
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public List<T> findAll() {
		return this.getRepository().findAll();
	}
	
	/**
	 * 根据实体对象查询
	 * @param entity 过滤的实体对象， 不为null的属性都会参与过滤
	 * @return 实体列表
	 */
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public <S extends T> List<S> findAll(S entity) {
		Example<S> example = Example.of(entity);
		return this.getRepository().findAll(example);
	}
	
	/**
	 * 根据实体对象查询, 分页查询
	 * @param entity 过滤的实体对象， 不为null的属性都会参与过滤
	 * @param pageable 分页排序信息
	 * @return  分页实体列表
	 */
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public <S extends T> Page<S> findAll(S entity, Pageable pageable) {
		Example<S> example = Example.of(entity);
		return this.getRepository().findAll(example, pageable);
	}


	
}
